package com.yj.lottery_system.service.activityStatus.impl;

import com.yj.lottery_system.common.errorcode.ServiceErrorCodeConstants;
import com.yj.lottery_system.common.exception.ServiceException;
import com.yj.lottery_system.service.IActivityService;
import com.yj.lottery_system.service.activityStatus.IActivityStatusManager;
import com.yj.lottery_system.service.activityStatus.operator.AbstractActivityOperator;
import com.yj.lottery_system.service.dto.ConvertActivityStatusDTO;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Service
public class ActivityStatusManagerImpl implements IActivityStatusManager {
    private static final Logger log = LoggerFactory.getLogger(ActivityStatusManagerImpl.class);
    @Autowired
    private  Map<String, AbstractActivityOperator> operatorMap = new HashMap<>();
   @Resource
   private IActivityService activityService;
    /**
     * 处理活动相关状态转换
     * @param convertActivityStatusDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handleEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        if(CollectionUtils.isEmpty(operatorMap)) {
            log.warn("operatorMap 为空");
            return;
        }

        //拿到需要处理的
        Map<String, AbstractActivityOperator> curMap = new HashMap<>(operatorMap);

        //更新标志位
        Boolean updateFlag = false;
        //先处理
        updateFlag = processConvertStatus(convertActivityStatusDTO,curMap,1);
        //后处理
        updateFlag = processConvertStatus(convertActivityStatusDTO,curMap,2) || updateFlag;
        //更新过，更新缓存
        if(updateFlag) {
            activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
        }
    }
    /**
     * 处理活动相关状态回滚
     * @param convertActivityStatusDTO
     */
    @Override
    public void rollBackHandleEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        //拿到需要处理的
        Map<String, AbstractActivityOperator> curMap = new HashMap<>(operatorMap);
        for(AbstractActivityOperator operator : curMap.values()) {
            operator.convert(convertActivityStatusDTO);
        }
        //更新缓存
        activityService.cacheActivity(convertActivityStatusDTO.getActivityId());

    }

    /**
     * 扭转 curMap 里面 sequence 的状态
     * @param convertActivityStatusDTO
     * @param curMap
     * @param sequence
     * @return
     */

    private Boolean processConvertStatus(ConvertActivityStatusDTO convertActivityStatusDTO,
                                         Map<String, AbstractActivityOperator> curMap,
                                         int sequence) {
        //更新标志位
        Boolean updateFlag = false;
        //遍历 curMap
        Iterator<Map.Entry<String, AbstractActivityOperator>> iterator = curMap.entrySet().iterator();
        while(iterator.hasNext()) {
            AbstractActivityOperator operator = iterator.next().getValue();
            //判断operator是否需要扭转状态
            if(operator.sequence() != sequence
            || !operator.needConvert(convertActivityStatusDTO)) {
                continue;
            }

            //需要扭转 扭转状态
            if(!operator.convert(convertActivityStatusDTO)) {
                log.error("{} 状态扭转失败 ",operator.getClass().getName());
                throw new ServiceException(ServiceErrorCodeConstants.ACTIVITY_STATUS_CONVERT_ERROR);
            }
            //在curMap删除当前operator
            iterator.remove();
            updateFlag = true;
        }

        //返回
        return updateFlag;
    }
}
